XMLHttpRequest 常简称 XMR ,中文可以理解为可扩展超文本传输请求。 XMLHttpRequest 对象可以在不向服务器提交整个页面的情况下,实现局部更新。
XMLHttpRequest 对象老版本缺陷
XHR 2 的新版功能:
新版本的 XMLHttpRequest 对象增加 timeout 属性,可以设置 HTTP 请求时限。
hr.timeout = int || function();
目前, Opera 、 Firefox 支持该属性, Chrome 、 Safari 不支持。
为了方便表单处理, HTML 5 新增了一个 FormData 对象,可以模拟表单。
新建表单
var formData = new FormData();
为 FormData 对象添加表单项
formData.append('username', ' 王五 ');
formData.append('id', 123456);
直接传送这个 FormData 对象这与提交网页表单一个效果
xhr.send(formData);
FormData 也可以获取网页表单的值:
var form = mi('#form');
var formData = new FormData(form);
formData.append('secret', '123456'); // 添加表单项
xhr.open('POST', form.action);
xhr.send(formData);
将 input[type='file'] 元素装入 FormData 对象:
var formData = new FormData();
for (let i = 0; i < file.length; i++) {
formData.append('file[]', files[i]);
}
然后,发送这个 FormData 对象:
xhr.send(formData);
新版本的 XMLHttpRequest 对象,可以跨域向服务器发送 HTTP 请求,也称为跨域资源共享( Cross-Origin Resource Sharing,CORS )。
在 HTML 5 之前,当使用 XMLHttpRequest 对象从服务器端获取二进制数据时,通常需要 XMLHttpRequest 对象的 overrideMimeType() 方法重载
var xhr = new XMLHttpRequest();
xhr.open('GET', 'test.png', true);
xhr.overrideMimeType('text/plain;charset=x-user-defined');
xhr.onreadystatechange = function (e) {
if (this.readyState == 4 && this.status == 200) {
var binStr = this.responseText;
for (let i = 0; (len = binStr.length); i++) {
var c = binStr.charCodeAt(i);
var byte = c & 0xff; // type at offset i
}
}
};
上述方法可以获取二进制数据,但是 XMLHttpRequest 对象的 responseText 属性值的返回值并不是原始的二进制数据,而是由这些数据所组成的和字符串。
HTML 5 为 XMLHttpRequest 新增属性 responseType 和 response 。
response : 如果想服务器请求成功,真返回响应数据
老版本的 XMLHttpRequest 对象只能从服务器接受文本数据,新版可以接收二进制数据。
传统方法实现是将改写数据的 MIME Type ,将服务器返回的二进制数据伪装成文本数据,并且告诉浏览器这是用户自定义的字符集。
xhr.overrideMimeType('text/plain;charset=x-user-defined');
然后,用 responseText 属性接收服务器返回的二进制数据。再一个字节一个字节翻译回来:
var binStr = this.responseText;
for (let i = 0; (len = binStr.length); i++) {
var c = binStr.charCodeAt(i);
var byte = c & 0xff; // type at offset
}
最后一行的位运算符 'c & 0xff' ,表示每一个字符的两个字节中,只保留最后一个字节,将钱一个字节扔掉。原因是浏览器解读字符的时候,会把字符自动解读成 Unicode 的 OxF700 ~ 0xF7ff 区段。
在新的浏览器中,使用 responseType 属性,定义为 blob ,即为二进制数据。
var xhr = new XMLHttpRequest();
xhr.open('GET', '/path/to/image.png');
xhr.responseType = 'blob';
接收数据时,使用浏览器自带的 Blob 对象即可:
var blob = new Blob([xhr.response], { type: 'image/png' });
可以将 responseType 设置为 arrayBuffer ,把二进制装进一个数组中:
var xhr = new XMLHttpRequest();
xhr.open('GET', 'path/to/image.png');
xhr.responseType = 'ArrayBuffer';
接收数据时,需要遍历数组:
var arrayBuffer = xhr.response;
if (arrayBuffer) {
var byteArray = new Unit8Array(arrayBuffer);
for (let i = 0; i < byteArray.length; i++) {
//
}
}
新版本的 XMLHttpRequest 对象,传输数据时,有一个 progress 事件,用来返回进度信息。它分为上传和下载两种情况。下载的 progress 事件属于 XMLHttpRequest 对象,上传的 progress 属于 XMLHttpRequest.upload 事件。
xhr.onprogress = updateProgress;
xhr.update.onprogress = updateProgress;
在回调函数,使用这些属性:
function update(event) {
if (event.lengthComputable) {
var percentComplete = event.loaded / event.total;
}
}
event.total 是需要传输的字节, event.loaded 是已经传输的字节。如果 event.lengthComputable 不为真,则 event.total 等于 0 ;
与 progress 相关的其他 5 个事件,可以分别指定回调函数: